home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
glass
/
glass.lha
/
GLASS
/
dtm
/
typecache.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-18
|
3KB
|
141 lines
/*
File: typecache.c
*/
#include <strings.h>
#include <stdio.h>
#include <cvr.h>
#include <tmc.h>
#include "dtmconst.h"
#include "tmcode.h"
#include "utils.h"
#include "typecache.h"
/*
Because C has only name equivalence instead of type
equivalence for structures we must cache the coding
of all possible Glass types occurring in expressions
so that we may generate 'typedefs' aforehand for them.
*/
/*
Test for type equivalence
*/
int equal_typ (t1,t2)
typ t1,t2;
{ if (t1 -> tag != t2 -> tag) return (0);
switch (t1 -> tag)
{ case TAGTypBase: return (1);
case TAGTypIn:
return (equal_typ (t1 -> TypIn.ityp, t2 -> TypIn.ityp));
case TAGTypOut:
return (equal_typ (t1 -> TypOut.otyp, t2 -> TypOut.otyp));
case TAGTypUni:
return (equal_typ (t1 -> TypUni.uityp, t2 -> TypUni.uityp) &&
equal_typ (t1 -> TypUni.uotyp, t2 -> TypUni.uotyp));
case TAGTypNon:
return (equal_typ (t1 -> TypNon.nontyp, t2 -> TypNon.nontyp));
case TAGTypProd:
{ typ_list t1l = t1 -> TypProd.ptypes,
t2l = t2 -> TypProd.ptypes;
register int ix;
if (t1l -> sz != t2l -> sz) return (0);
for (ix=0; ix < t1l -> sz; ix++)
if (!(equal_typ (t1l -> arr[ix], t2l -> arr [ix])))
return (0);
return (1);
};
case TAGTypSym:
{ return (0);
};
default: badtag (t1 -> tag);
};
};
/*
Store type in type cache.
*/
#define MaxTypeCache 1000
static int typnr=0;
static typ cached_types[MaxTypeCache];
void add_to_cache (t)
typ t;
{ int ix;
typ_list tl;
if (t -> tag == TAGTypBase) return;
if (t -> tag != TAGTypProd)
{ fprintf (stderr, "Only product types may be cached\n");
};
for (ix=0; ix < typnr; ix++)
if (equal_typ (t, cached_types[ix]))
return;
tl = t -> TypProd.ptypes;
for (ix = 0; ix < tl -> sz; ix++)
add_to_cache (tl -> arr[ix]);
cached_types [typnr] = rdup_typ (t);
typnr++;
};
/*
code type using the cache
*/
void code_typ (f,t)
FILE *f;
typ t;
{ switch (t -> tag)
{ case TAGTypBase:
fprintf (f, "int");
break;
case TAGTypProd:
{ register int ix;
for (ix=0; ix < typnr; ix++)
if (equal_typ (t, cached_types [ix]))
{ fprintf (f, "typ%d", ix);
return;
};
fprintf (stderr, "type not cached\n");
exit (1);
};
break;
default: badtag (t -> tag);
};
};
/*
code the cached types
*/
void code_cached_types (f)
FILE *f;
{ int ix;
for (ix = 0; ix < typnr; ix++)
{ int iy;
typ_list tl = cached_types[ix] -> TypProd.ptypes;
fprintf (f, "typedef ");
if (tl -> sz == 0)
{ fprintf (f, "void ");
}
else
{ fprintf (f, "struct\n { ");
for (iy=0; iy < tl -> sz; iy++)
{ code_typ (f, tl -> arr[iy]);
fprintf (f, " f%d;\n", iy);
if (iy != tl -> sz - 1)
fprintf (f, " ");
};
fprintf (f, " } ");
};
fprintf (f, "typ%d;\n\n", ix);
};
};
/*
flush the cached types
*/
void flush_cached_types ()
{ int ix;
for (ix = 0; ix < typnr; ix++)
rfre_typ (cached_types [ix]);
typnr = 0;
};